package hkust.ee.fyp;

import hkust.ee.fyp.tool.Directory;
import hkust.ee.fyp.tool.TouchGestureDetector;
import hkust.ee.fyp.tool.TouchGestureDetector.OnGestureListener;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.widget.ImageView;
import android.widget.Toast;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.AsyncFacebookRunner.RequestListener;

public class PhotoViewer extends Activity {

	private TouchGestureDetector gestureDetector = null;
	private ImageView imageView = null;

	private static int screenWidth, screenHeight;
	private float imageWidth,imageHeight;

	protected static final int MENU_SLIDESHOW = Menu.FIRST;
	protected static final int MENU_SHARE = Menu.FIRST + 1;
	protected static final int MENU_EDIT = Menu.FIRST + 2;
	private boolean fromFolder = false;

	protected static final int CROP_IMAGE = 100;
	protected static final int EDIT_IMAGE = 200;

	private List<Uri> imgList;
	private ImageView screenSaverView;
	private boolean screenSaverRunning = false;
	private long intervalScreenSaver = 7000;
	private int intDrawable = 0;
	private Handler ScreenSaverHandler = new Handler();
	private AnimationSet animationSet = new AnimationSet(false);

	private Directory directory = null;
	private Uri uri = null;
	
	public static final String TEMP_CROP_FOLDER = "/sdcard/.temp/";
	public static final String TEMP_CROP_NAME = "temp.jpg";
	
	//facebook
	private static final String APP_ID = "207571395929037";
	private Facebook facebook = new Facebook(APP_ID);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		SharedPreferences settings = getSharedPreferences(PhotoFrame.TAG, 0);
		facebook.setAccessToken(settings.getString("facebookToken", null));		

		setContentView(R.layout.gallery_single);

		imageView = (ImageView) this
				.findViewById(R.id.gallery_single_imageView);

		getScreenSize();
		
		uri = getIntent().getData();
		if (uri != null) {
			try {
				Bitmap bmp = BitmapFactory.decodeFile(uri.getPath());		
				imageView.setImageBitmap(bmp);
				
				imageHeight = bmp.getHeight();
				imageWidth = bmp.getWidth();
			} catch (OutOfMemoryError e) {
				try {					
					int maxLength = (int)(Math.max(screenHeight, screenWidth) *1.5);	  
					BitmapFactory.Options opts = new BitmapFactory.Options();  	
					opts.inJustDecodeBounds = true;
					BitmapFactory.decodeFile(uri.getPath(), opts);  
  
					int srcWidth = opts.outWidth;  		  
					int srcHeight = opts.outHeight;  
  
					int destWidth = 0;  		  
					int destHeight = 0;  
  
					double ratio = 0.0;
  
					if(srcWidth >srcHeight) {
					    ratio = srcWidth / maxLength;  
					    destWidth = maxLength;  
					    destHeight = (int) (srcHeight / ratio);
					}else {  
					    ratio = srcHeight / maxLength;
					    destHeight = maxLength;  
					    destWidth = (int) (srcWidth / ratio);
					}  
					
					BitmapFactory.Options newOpts = new BitmapFactory.Options();  
					newOpts.inSampleSize = (int) ratio + 1;  
					newOpts.inJustDecodeBounds = false;  
					newOpts.outHeight = destHeight;
					newOpts.outWidth = destWidth;  
					
					Bitmap bmp = BitmapFactory.decodeFile(uri.getPath(), newOpts);		
					imageView.setImageBitmap(bmp);
					imageHeight = bmp.getHeight();
					imageWidth = bmp.getWidth();
					Toast.makeText(this, "File too Big.\nDownsizing",Toast.LENGTH_LONG).show();
				} catch (Exception e1) {
					e1.printStackTrace();
				} 
				
			}
			getScreenSize();
			OnGestureListener gestureListener = new OnGestureListener() {

				public void onDrag(float dx, float dy) {
//					og.d("", "onDrag " + dx + " " + dy);
					PhotoViewer.this.imageView
						.setScaleType(ImageView.ScaleType.MATRIX);
					Matrix matrix = PhotoViewer.this.imageView.getImageMatrix();
					float[] values = new float[9];
					matrix.getValues(values);
					float mtrans_x = values[Matrix.MTRANS_X];
					float mtrans_y = values[Matrix.MTRANS_Y];
					float mscale_x = values[Matrix.MSCALE_X] ;
					float mscale_y = values[Matrix.MSCALE_Y] ;
					
//					for(float f : values){
//						Log.d("matrx-start", f+" ");
//					}
					if(mtrans_x + dx <screenWidth && mtrans_x + imageWidth*mscale_x + dx> 0){
						
					}else{
						dx=0;
					}
					if(mtrans_y + dy <screenHeight && mtrans_y + imageHeight*mscale_y + dy> 0){
						
					}else{
						dy=0;
					}
					matrix.postTranslate(dx, dy);;
					matrix.getValues(values);
//					for(float f : values){
//						Log.d("matrx-end", f+" ");
//					}
					PhotoViewer.this.imageView.setImageMatrix(matrix);
					PhotoViewer.this.imageView.invalidate();					

				}

				public void onScale(float scaleFactor) {
					PhotoViewer.this.imageView
							.setScaleType(ImageView.ScaleType.MATRIX);
					Matrix matrix = PhotoViewer.this.imageView.getImageMatrix();			
					
					float[] values = new float[9];
					matrix.getValues(values);
					float scale = values[Matrix.MSCALE_X];
//					for(float f : values){
//						Log.d("matrx-start", f+" ");
//					}
					
					float t = scale * scaleFactor;
					if(t > 4){
//						scale = 4;
					}
					else if(t<1){
//						scale = 1; 
					}
					else{
						scale = t;
						matrix.postScale(scaleFactor, scaleFactor,
								screenWidth / 2,screenHeight / 2);
					}
//					for(float f : values){
//						Log.d("matrx-end", f+" ");
//					}
					PhotoViewer.this.imageView.setImageMatrix(matrix);
					PhotoViewer.this.imageView.invalidate();
				}

			};
			gestureDetector = TouchGestureDetector.newInstance(this,
					gestureListener);
			imageView.setOnTouchListener(new OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					return gestureDetector.onTouchEvent(event);
				}

			});

			String path = uri.getPath();
			File file = new File(path.substring(0, path.lastIndexOf("/")));
			directory = Directory.getDirectoryData(file);
			imgList = directory.getImageList();
		}
		
		screenSaverView = (ImageView) findViewById(R.id.screenSaver);	
		animationSet = new AnimationSet(false);
		
		AlphaAnimation fadeIn = new AlphaAnimation (0,1);
		fadeIn.setDuration(1000);
		
		AlphaAnimation fadeOut = new AlphaAnimation (1,0);
		fadeOut.setStartOffset(6000);
		fadeOut.setDuration(1000);
		
		animationSet.addAnimation(fadeIn);
		animationSet.addAnimation(fadeOut);

		fromFolder = getIntent().getBooleanExtra("slideshow", false);
		if(fromFolder){
			slideShow();
			String path = getIntent().getStringExtra("directory");
			try {
				File file = new File(path);
				directory = Directory.getDirectoryData(file);
				imgList = directory.getImageList();
			} catch (Exception e) {
				finish();
			}
		}
		
		
	}

	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);		
		if(fromFolder){
			menu.add(0, MENU_SLIDESHOW, 0, "Stop slideshow");			
		}else{
			menu.add(0, MENU_SHARE, 0, "Share");
			menu.add(0, MENU_EDIT, 0, "Create sticker photo");
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);
		switch (item.getItemId()) {
		case MENU_SLIDESHOW:{
			slideShow();
		}
			break;
		case MENU_SHARE:{
//			Intent intent = new Intent(Intent.ACTION_VIEW);
//			intent.setClass(this,hkust.ee.fyp.facebook.FacebookActivity.class);
//			intent.putExtra(name, value)
			// intent.setClass(v.getContext(),
			// hkust.ee.fyp.drawer.MainActivity.class);
//			startActivity(intent);
			facebookUploadPhoto(uri.getPath());
		}
			break;
		case MENU_EDIT:{
			
			Intent intent = new Intent();
			intent.setClass(this,hkust.ee.fyp.tool.MyCropImage.class);
			intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
			intent.putExtra("crop", "true");
			intent.putExtra("aspectX", 3);
			intent.putExtra("aspectY", 4);
			intent.putExtra("outputX", 540);
			intent.putExtra("outputY", 720);
			intent.putExtra("scale", true);
//			intent.putExtra("return-data", true);
			intent.putExtra("return-data", false);
			intent.putExtra("output-name",TEMP_CROP_NAME);
			intent.putExtra("output-folder", TEMP_CROP_FOLDER);
			
			try {
				startActivityForResult(intent, CROP_IMAGE);
			} catch (ActivityNotFoundException e1) {
//				e1.printStackTrace();
			}

			break;
			}
		}
		return true;
	}


	private void slideShow() {
		if (!screenSaverRunning) {
			screenSaverRunning = !screenSaverRunning;
			ScreenSaverHandler.postDelayed(showScreenSaver, 100);
			hideOriginalLayout();
		} else {
			onKeyDown(KeyEvent.KEYCODE_BACK,null);	
		}
		
	}

	private void showOriginalLayout() {
		imageView.setVisibility(View.VISIBLE);
		screenSaverView.setVisibility(View.GONE);
	}

	private void hideOriginalLayout() {
		imageView.setVisibility(View.GONE);
		screenSaverView.setVisibility(View.VISIBLE);
	}

	private Runnable showScreenSaver = new Runnable() {
		public void run() {
			if (screenSaverRunning) {
				if (intDrawable > PhotoViewer.this.imgList.size() - 1) {
					intDrawable = 0;
				}

				int maxLength = Math.max(screenHeight, screenWidth);	  
		        BitmapFactory.Options opts = new BitmapFactory.Options();  	
		        opts.inJustDecodeBounds = true;
		        BitmapFactory.decodeFile(imgList.get(intDrawable).getPath(), opts);  
		  
		        int srcWidth = opts.outWidth;  		  
		        int srcHeight = opts.outHeight;  
		  
		        int destWidth = 0;  		  
		        int destHeight = 0;  
		  
		        double ratio = 0.0;
		  
		       if(srcWidth >srcHeight) {
			        ratio = srcWidth / maxLength;  
			        destWidth = maxLength;  
			        destHeight = (int) (srcHeight / ratio);
		        }else {  
		            ratio = srcHeight / maxLength;
		            destHeight = maxLength;  
		            destWidth = (int) (srcWidth / ratio);
		        }  
		  
		        BitmapFactory.Options newOpts = new BitmapFactory.Options();  
		        newOpts.inSampleSize = (int) ratio + 1;  
		        newOpts.inJustDecodeBounds = false;  
		        newOpts.outHeight = destHeight;
		        newOpts.outWidth = destWidth;  
				
				Bitmap bmp = BitmapFactory.decodeFile(imgList.get(intDrawable)
						.getPath(), newOpts); 
				float scaleWidth = ((float) screenWidth) / bmp.getWidth();
				float scaleHeight = ((float) screenHeight) / bmp.getHeight();
				float commonScale = Math.min(scaleWidth, scaleHeight);
				Matrix matrix = new Matrix();
				matrix.postScale(commonScale, commonScale);
				Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0,
						bmp.getWidth(), bmp.getHeight(), matrix, true);
				BitmapDrawable myNewBitmapDrawable = new BitmapDrawable(
						resizedBitmap);
				screenSaverView.setImageDrawable(myNewBitmapDrawable);
				screenSaverView.setVisibility(View.VISIBLE);
				
				screenSaverView.setAnimation(animationSet);
				animationSet.startNow();
				
				intDrawable++;
				ScreenSaverHandler.postDelayed(showScreenSaver,
						intervalScreenSaver);

			} else {
				ScreenSaverHandler.removeCallbacks(showScreenSaver);
				showOriginalLayout();
			}

		}
	};

	private void getScreenSize() {
		Display display = getWindowManager().getDefaultDisplay();
		screenHeight = display.getHeight();
		screenWidth = display.getWidth();
	}

	public void onConfigurationChanged(Configuration newConfig) {
		getScreenSize();
		super.onConfigurationChanged(newConfig);
	}

	public boolean onKeyDown(int keyCode, KeyEvent msg) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (screenSaverRunning) {
				List<Animation> aSet = animationSet.getAnimations();
				for(Animation a : aSet){
					a.cancel();
				}				
				screenSaverRunning = false;
				intDrawable = 0;
				ScreenSaverHandler.removeCallbacks(showScreenSaver);
				
				if(fromFolder){
					 finish();
				}else{
					showOriginalLayout();	
				}
				return true;
			}
		}
		return super.onKeyDown(keyCode, msg);
	}

	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		facebook.authorizeCallback(requestCode, resultCode, data);

		if (resultCode != RESULT_OK) {
			return;
		}

		switch (requestCode) {
			case CROP_IMAGE: 
				final Bundle extras = data.getExtras();
				if (extras != null) {					
					Intent intent = new Intent();
//					Log.d("return", extras.getString("path"));					
					intent.putExtras(extras);
					intent.setClass(this, hkust.ee.fyp.drawer.DrawerActivity.class);
					startActivityForResult(intent, EDIT_IMAGE);
				}
				break;
			case EDIT_IMAGE:
				
				break;
		}

	}
	
	public void facebookUploadPhoto(String pathName) {
		if (!facebook.isSessionValid()) {
			Toast.makeText(this, "Please login first", Toast.LENGTH_SHORT).show();
			return;
		}
		
		byte[] data = null;

		Bitmap bi = BitmapFactory.decodeFile(pathName);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
		data = baos.toByteArray();

		final Bundle params = new Bundle();
		params.putString("method", "photos.upload");
		params.putByteArray("picture", data);
		
		AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
		mAsyncRunner.request(null, params, "POST",
				new RequestListener() {
					@Override
					public void onComplete(String response, Object state) {
						Log.d("UPLOAD", "complete");
						
						NotificationManager mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
						Notification notification = new Notification(R.drawable.icon,"PhotoFrame", System.currentTimeMillis());
						notification.setLatestEventInfo(PhotoViewer.this,"upload", "finish...",
						PendingIntent.getActivity(PhotoViewer.this, 0, null,	PendingIntent.FLAG_ONE_SHOT));
					    mManager.notify(0, notification);
					}

					@Override
					public void onIOException(IOException e, Object state) {
						Log.d("UPLOAD", "io exception");
					}

					@Override
					public void onFileNotFoundException(
							FileNotFoundException e, Object state) {
						Log.d("UPLOAD", "file not found");
					}

					@Override
					public void onMalformedURLException(
							MalformedURLException e, Object state) {
						Log.d("UPLOAD", "url exception");
					}

					@Override
					public void onFacebookError(FacebookError e, Object state) {
						Log.d("UPLOAD", "error");
					}

				}, null);
	}
	
}
